Skip to content

refactor: replace dict-based config with type-safe vendor classes#4

Merged
mattblank11 merged 2 commits into
mainfrom
devin/1771970423-type-safe-vendors
Feb 24, 2026
Merged

refactor: replace dict-based config with type-safe vendor classes#4
mattblank11 merged 2 commits into
mainfrom
devin/1771970423-type-safe-vendors

Conversation

@fern-support

@fern-support fern-support commented Feb 24, 2026

Copy link
Copy Markdown
Collaborator

refactor: replace dict-based config with type-safe vendor classes

Summary

Replaces the old shorthand-string and dict-based vendor configuration (Agent(llm="openai/gpt-4")) with type-safe Pydantic vendor classes. This is a breaking API change — the previous AgentOptions TypedDict and all shorthand parsing functions are removed.

New API pattern:

from agoraio.wrapper import Agent
from agoraio.wrapper.vendors import OpenAI, ElevenLabsTTS, DeepgramSTT

agent = (
    Agent(instructions="You are a helpful assistant.")
    .with_llm(OpenAI(api_key="...", model="gpt-4"))
    .with_tts(ElevenLabsTTS(key="...", model_id="...", voice_id="...", sample_rate=24000))
    .with_stt(DeepgramSTT(api_key="..."))
)

What's new:

  • vendors/ package with base classes (BaseLLM, BaseTTS, BaseSTT, BaseMLLM, BaseAvatar) and concrete implementations for ~30 vendors
  • Pydantic BaseModel validation with extra = "forbid" on all vendor option classes
  • Literal type aliases for vendor-specific sample rates (e.g., ElevenLabsSampleRate, CartesiaSampleRate)
  • Avatar/TTS sample rate compatibility validation at both with_avatar() time and session start

What's removed:

  • AgentOptions TypedDict
  • _parse_llm_shorthand(), _parse_tts_shorthand(), _parse_stt_shorthand()
  • avatar_types.py (validation logic moved into Agent and AgentSession)

Updates since last revision

  • Removed stale exports from src/agoraio/__init__.py: AgentOptions, is_heygen_avatar, is_akool_avatar, validate_avatar_config, validate_tts_sample_rate were still referenced in the top-level __init__.py but no longer exist in the wrapper module. This was causing the mypy CI check to fail.

Review & Testing Checklist for Human

⚠️ This is a breaking change with no backward compatibility.

  • Verify config dict keys match Agora API expectations: The vendor to_config() methods produce dicts with keys like "vendor", "params", "api_key", etc. These must exactly match what the generated Agora SDK types expect. Test with a real API call to ensure no field name mismatches — CI only checks types, not runtime correctness.
  • Test avatar/TTS sample rate validation: Create an agent with .with_avatar(HeyGenAvatar(...)) (requires 24kHz) and .with_tts(ElevenLabsTTS(..., sample_rate=16000)) (wrong rate). Verify it raises ValueError at with_avatar() time. Also test the reverse order (TTS after avatar) to ensure AgentSession._validate_avatar_config() catches it.
  • Verify Pydantic validation works: Try creating a vendor with invalid params (e.g., OpenAI(api_key="", model=123) or ElevenLabsTTS(key="", model_id="", voice_id="", sample_rate=99999)). Confirm Pydantic raises ValidationError with helpful messages.
  • Check IDE autocomplete: Open the SDK in an IDE and verify that typing OpenAI( shows autocomplete for api_key, model, etc. with type hints.

Notes

  • No unit tests were added in this PR. Consider adding tests for vendor class instantiation, to_config() output, and avatar/TTS validation logic.
  • The OpenAITTS.sample_rate property always returns 24000 (hardcoded) since OpenAI TTS only supports 24kHz output.
  • All vendor option classes use extra = "forbid" to catch typos in keyword arguments.
  • Go SDK has equivalent changes in refactor: replace dict-based config with type-safe vendor classes agora-agents-go#6

Link to Devin run: https://app.devin.ai/sessions/756e000c856649af9c8655b0ef4e1038
Requested by: @fern-support

Co-Authored-By: blank@buildwithfern.com <blank@buildwithfern.com>
@devin-ai-integration

Copy link
Copy Markdown

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

Co-Authored-By: blank@buildwithfern.com <blank@buildwithfern.com>
@mattblank11 mattblank11 merged commit ffa4ae6 into main Feb 24, 2026
3 checks passed
@digitallysavvy digitallysavvy deleted the devin/1771970423-type-safe-vendors branch March 5, 2026 22:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants